#import "AppViewController.h"
#import "SBJSON.h"
#import "UIDevice-Hardware.h"
#import "MainPageViewController.h"

//#import <AVFoundation/AVFoundation.h>
//#import <CoreAudio/CoreAudioTypes.h>
//#import "MediaPlayer/MediaPlayer.h"
//#import <QuartzCore/QuartzCore.h>
//#import "cocos2d.h"
//#import "CDAudioManager.h"

@interface AppViewController ()

@end


@implementation AppViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        _listOfViewController = [NSMutableArray new];
        _APIRequester = [APIRequester new];
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/////////////////////////////////
static AppViewController *_appVCInstance;
+ (AppViewController *)Shared
{
    if (!_appVCInstance) {
        _appVCInstance = [[AppViewController alloc] init];
    }
    return _appVCInstance;
}

- (void)popViewControllerAnimated:(BOOL)animated {
    if (animated) {
        if ([UIDevice currentDevice].systemVersion.floatValue < 6) {
            CATransition* transition = [CATransition animation];
            transition.duration = TIMER_CHANGING_VIEW*2;
            
            // CASE 1:
//            transition.type = kCATransitionPush;
//            
//            if ([UIDevice currentDevice].orientation == UIInterfaceOrientationLandscapeLeft) {
//                transition.subtype = kCATransitionFromTop;
//            }
//            else {
//                transition.subtype = kCATransitionFromBottom;
//            }
            
            // CASE 2:
            transition.type = kCATransitionFade;
            
            [self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
            [self.navigationController popViewControllerAnimated:NO];
        }
        else {
            [self.navigationController popViewControllerAnimated:YES];
        }
    }
    else {
        [self.navigationController popViewControllerAnimated:NO];
    }
}

- (void)popToRootViewControllerAnimated:(BOOL)animated {
    if (animated) {
        CATransition* transition = [CATransition animation];
        transition.duration = TIMER_CHANGING_VIEW*2;
        
        // CASE 1:
//        transition.type = kCATransitionPush;
//        if ([UIDevice currentDevice].orientation == UIInterfaceOrientationLandscapeLeft) {
//            transition.subtype = kCATransitionFromTop;
//        }
//        else {
//            transition.subtype = kCATransitionFromBottom;
//        }
        
        // CASE 2:
        transition.type = kCATransitionFade;
        
        [self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
        
        [self.navigationController popToRootViewControllerAnimated:NO];
    }
    else {
        [self.navigationController popToRootViewControllerAnimated:NO];
    }
}

#pragma mark - Indicator view animation

- (void)isRequestingAndShouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    if (_requestingView) {
        _requestingIndicator.center = _requestingView.center;
        _requestingIndicator.frame = CGRectOffset(_requestingIndicator.frame, 0, -_requestingIndicator.frame.size.height);
    }
}

- (void)isRequesting:(BOOL)isRe andRequestType:(ENUM_API_REQUEST_TYPE)type andFrame:(CGRect)frame {
    if (isRe) {
        if (_requestingView == nil) {
            _requestingView = [UIView new];
            _requestingView.backgroundColor = [UIColor blackColor];
            _requestingView.alpha= 0.5;
        }
        if (_requestingIndicator == nil) {
            _requestingIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
            [_requestingView addSubview:_requestingIndicator];
            
        }
        
        [_requestingView removeFromSuperview];
        [_requestingIndicator startAnimating];
		_requestingView.frame = frame;
		_requestingIndicator.center = CGPointMake(frame.size.width / 2, frame.size.height / 2);
        [[[_listOfViewController lastObject] view] addSubview:_requestingView];
    }
    else {
        [_requestingIndicator stopAnimating];
        [_requestingView removeFromSuperview];
    }
}

#pragma mark - App Protocol
/////////////////////////////////
- (void)update {
    // update top view controller
    if ([_listOfViewController lastObject]) {
        id<AppViewControllerProtocol> vc = [_listOfViewController lastObject];
        if ([vc respondsToSelector:@selector(update)]) {
            [vc update];
        }
    }
    
    // Request API server automatically
    if ([[AutomationDataManager Shared] respondsToSelector:@selector(update)]) {
        [[AutomationDataManager Shared] update];
    }
}

#pragma mark - HomeViewController
/////////////////////////////////
- (void)changeToHomeFromWelcomeScreen:(BOOL)isFromLogin {
    if (isFromLogin) {
        [_listOfViewController removeAllObjects];
        [self.navigationController popToRootViewControllerAnimated:NO];
    }
    
    // TODO:
    HomeViewController *homeVC = [HomeViewController new];
    [_listOfViewController addObject:homeVC];
    [self.navigationController pushViewController:homeVC animated:NO];
}
- (void)changeBackToHome {
    [_listOfViewController removeAllObjects];
    [self popToRootViewControllerAnimated:YES];
    
    // TODO:
    HomeViewController *homeVC = [HomeViewController new];
    [_listOfViewController addObject:homeVC];
    [self.navigationController pushViewController:homeVC animated:NO];
}

#pragma mark - SplashScreenViewController
/////////////////////////////////
- (void)changeToSplashScreen {
//    SplashScreenViewController *splashVC = [SplashScreenViewController new];
//    
//    [_listOfViewController addObject:splashVC];
//    [self.navigationController pushViewController:splashVC animated:NO];
    
    // CASE 2:
    // MinhPB 2013/06/16
    [self changeToHomeFromWelcomeScreen:YES];
}
- (void)changeBackFromSplashScreen {
    [_listOfViewController removeLastObject];
    [self popViewControllerAnimated:NO];
    
    // MinhPB 2012/11/20
//    [self changeToWelcome];
    [self changeToHomeFromWelcomeScreen:YES];
}

#pragma mark - MainPageViewController
- (void)changeToMainPageViewController; {
    MainPageViewController *tempVC = [MainPageViewController new];
    
    [_listOfViewController addObject:tempVC];
    [self.navigationController pushViewController:tempVC animated:YES];
}
- (void)changeBackFromMainPageViewController; {
    [_listOfViewController removeLastObject];
    [self popViewControllerAnimated:YES];
}

#pragma mark - FEEDBACK

- (void)changeToFeedbackVCWithEmailAddress:(NSString *)emailAddress; {
    // TIME
    NSDate *date = [NSDate date];
    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"MMMM-dd-YYYY HH:mm:ssZZZ"];
    NSString *dateString = [dateFormat stringFromDate:date];
    
    // RECIPENTS
    NSMutableArray *recipents = [NSArray arrayWithObject:emailAddress];
    
    // ATTACHMENT
    NSData *attachmentData = nil;
    NSString *attachmentName = @"";
    
    [self changeToPostingMailWithRecipients:recipents andSubject:[NSString stringWithFormat:@"%@ (%@, %@)", @"FEEDBACK", @"Phòng Đẹp.vn", dateString] andBody:@"" andAttachmentData:attachmentData andAttachmentName:attachmentName];
}

- (void)changeBackToPreviousViewController; {
    [_listOfViewController removeLastObject];
    [self popViewControllerAnimated:YES];
}

#pragma mark - Mail Protocol
/////////////////////////////////
- (void)changeToPostingMailWithRecipients:(NSMutableArray *)recipients andSubject:(NSString *)subject andBody:(NSString *)body andAttachmentData:(NSData *)attachmentData andAttachmentName:(NSString *)attachmentName
{
    Class mailClass = (NSClassFromString(@"MFMailComposeViewController"));
    if (mailClass != nil)
    {
        // We must always check whether the current device is configured for sending emails
        if([mailClass canSendMail])
        {
            [self displayComposerSheetWithRecipients:recipients andSubject:subject andBody:body andAttachmentData:attachmentData andAttachmentName:attachmentName];
        }
        else
        {
            [self launchMailAppOnDeviceWithRecipients:recipients andSubject:subject andBody:body andAttachmentData:attachmentData andAttachmentName:attachmentName];
        }
    }
    else
    {
        [self launchMailAppOnDeviceWithRecipients:recipients andSubject:subject andBody:body andAttachmentData:attachmentData andAttachmentName:attachmentName];
    }
}
- (void)changeBackFromPostingMail
{
    [self dismissModalViewControllerAnimated:YES];
}

// Displays an email composition interface inside the application. Populates all the Mail fields.
- (void)displayComposerSheetWithRecipients:(NSMutableArray *)recipients andSubject:(NSString *)subject andBody:(NSString *)body andAttachmentData:(NSData *)attachmentData andAttachmentName:(NSString *)attachmentName
{
	MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
	picker.mailComposeDelegate = self;
	
	[picker setSubject:subject];
	
    
	// Set up recipients
	NSArray *toRecipients = recipients;
	[picker setToRecipients:toRecipients];
    
    //    NSArray *ccRecipients = [NSArray arrayWithObject:@"fuminori.tomita@gmail.com"];
    //	[picker setCcRecipients:ccRecipients];
	
	// Fill out the email body text
	[picker setMessageBody:body isHTML:YES];
    
    // Attachment
    if (attachmentData) {
        [picker addAttachmentData:attachmentData mimeType:@"image/png" fileName:attachmentName];
    }
	
	[self presentModalViewController:picker animated:YES];
}

// Launches the Mail application on the device.
- (void)launchMailAppOnDeviceWithRecipients:(NSMutableArray *)recipients andSubject:(NSString *)subject andBody:(NSString *)body andAttachmentData:(NSData *)attachmentData andAttachmentName:(NSString *)attachmentName
{
	//NSString *recipients = @"mailto:first@example.com?cc=second@example.com,third@example.com&subject=Hello from California!";
	
	NSString *recipientAndSubject = [NSString stringWithFormat:@"mailto:%@?subject=%@", (NSString *)[recipients lastObject], subject];
	
	NSString *email = [NSString stringWithFormat:@"%@%@", recipientAndSubject, body];
	email = [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
	
	[[UIApplication sharedApplication] openURL:[NSURL URLWithString:email]];
}
// Dismisses the email composition interface when users tap Cancel or Send. Proceeds to update the message field with the result of the operation.
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
	NSString *message = @"";
	// Notifies users about errors associated with the interface
	switch (result)
	{
		case MFMailComposeResultCancelled:
//            message = @"Result: canceled";
            [self changeBackFromPostingMail];
			break;
		case MFMailComposeResultSaved:
//            message = @"Result: saved";
			break;
		case MFMailComposeResultSent:
//            message = @"Result: sent";
			break;
		case MFMailComposeResultFailed:
//            message = @"Result: failed";
			break;
		default:
//            message.text = @"Result: not sent";
            [self changeBackFromPostingMail];
			break;
	}
	
    if (message.length > 0) {
        ALERT_1(@"", message, self);
    }
}

//#pragma mark - Facebook & Twitter
//
//- (void)changeToFacebookViewController {
//    // CUSTOMIZE
//    [[FBFunLoginManager Shared] reLogin];
//    
//    [_listOfViewController addObject:[[FBFunLoginManager Shared] getFBControllerWithDelegate:self]];
//    [self presentModalViewController:[[FBFunLoginManager Shared] getFBControllerWithDelegate:self] animated:YES];
//    
//    //    // FRAMEWORK
//    //    // if the session is open, then load the data for our view controller
//    //    if (!FBSession.activeSession.isOpen) {
//    //        // if the session is closed, then we open it here, and establish a handler for state changes
//    //        [FBSession.activeSession openWithCompletionHandler:^(FBSession *session,
//    //                                                             FBSessionState state,
//    //                                                             NSError *error) {
//    //            switch (state) {
//    //                case FBSessionStateClosedLoginFailed:
//    //                {
//    //                    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error"
//    //                                                                        message:error.localizedDescription
//    //                                                                       delegate:nil
//    //                                                              cancelButtonTitle:@"OK"
//    //                                                              otherButtonTitles:nil];
//    //                    [alertView show];
//    //                }
//    //                    break;
//    //                default:
//    //                    break;
//    //            }
//    //        }];
//    //    }
//}
//
//- (void)changeBackFromFacebookViewController {
//    if ([FBFunLoginManager Shared].loginStatus) {
//        [_listOfViewController removeLastObject];
//        [self dismissModalViewControllerAnimated:NO];
//        
//        [self changeToFacebookPostViewController];
//    }
//    else {
//        [_listOfViewController removeLastObject];
//        [self dismissModalViewControllerAnimated:YES];
//    }
//}
//
///////////////////////////////////
//- (void)changeToTwitterViewController {
//    [[TWLoginManager Shared] reLogin];
//    
//    [_listOfViewController addObject:[[TWLoginManager Shared] getTWControllerWithDelegate:self]];
//    [self presentModalViewController:[[TWLoginManager Shared] getTWControllerWithDelegate:self] animated:YES];
//}
//
//- (void)changeBackFromTwitterViewController {
//    if ([TWLoginManager Shared].loginStatus) {
//        [_listOfViewController removeLastObject];
//        [self dismissModalViewControllerAnimated:NO];
//        
//        [self changeToTwitterPostViewController];
//    }
//    else {
//        [_listOfViewController removeLastObject];
//        [self dismissModalViewControllerAnimated:YES];
//    }
//}

#pragma mark - UIImage Picker View Controller

- (void)changeToPickerControllerWithSourceType:(UIImagePickerControllerSourceType)type andDelegate:(id<UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIPopoverControllerDelegate>)delegate {
    if ([UIImagePickerController isSourceTypeAvailable:type]) {
        if (INTERFACE_IS_PAD && type == UIImagePickerControllerSourceTypePhotoLibrary) {
            UIImagePickerController *picker = [[UIImagePickerController alloc] init];
            picker.sourceType = type;
            picker.delegate = delegate;
            if (!_popoverControllerMain) {
                _popoverControllerMain = [[UIPopoverController alloc] initWithContentViewController:picker];
                _popoverControllerMain.delegate = delegate;
            }
            [_popoverControllerMain presentPopoverFromRect:CGRectMake(0, 0, self.view.frame.size.width, 0) inView:[[UIApplication sharedApplication] keyWindow] permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
        }
        else {
            UIImagePickerController *picker = [[UIImagePickerController alloc] init];
            picker.sourceType = type;
            picker.delegate = delegate;
            if ([UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront] && type == UIImagePickerControllerSourceTypeCamera) {
                picker.cameraDevice = UIImagePickerControllerCameraDeviceFront;
            }
            
            self.navigationController.modalPresentationStyle = UIModalPresentationFullScreen;
            [self presentModalViewController: picker animated: YES];
        }
    }
    else {
        ALERT(@"", STRING_ALERT_MESSAGE_CAMERA_PHOTO_NOT_SUPPORTED);
    }
}
- (void)changeBackFromPickerController {
    [self dismissModalViewControllerAnimated:NO];
    [_popoverControllerMain dismissPopoverAnimated:NO];
}

#pragma mark - Application's Documents directory

// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

- (NSURL *)applicationCacheDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject];
}

#pragma mark - UserID & DeviceUDID & DeviceToken

- (void)requestUpdateUserID_Or_DeviceUDID_Or_DeviceToken
{
    // USER ID
    NSString *userID = [UIDevice currentDevice].deviceUDID;
    [UserDataManager Shared].userID = userID;
    
    // USER NAME
    NSString *userName = [UIDevice currentDevice].name;
    [UserDataManager Shared].userName = userName;
    
    // DEVICE UDID
    NSString *deviceUDID = [UIDevice currentDevice].deviceUDID;
    [UserDataManager Shared].userDeviceUDID = deviceUDID;
    
    
    // DEVICE TOKEN
    NSString *deviceToken = @"";
    if ([UserDataManager Shared].userRegisteredDeviceToken) {
        deviceToken = [UserDataManager Shared].userRegisteredDeviceToken;
        [UserDataManager Shared].userDeviceToken = [UserDataManager Shared].userRegisteredDeviceToken;
    }
    
    // UPDATE USER INFO
    NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
    [params setValue:deviceToken forKey:STRING_REQUEST_KEY_DEVICE_TOKEN];
    [params setValue:deviceUDID forKey:STRING_REQUEST_KEY_DEVICE_UDID];
    [params setValue:userID forKey:STRING_REQUEST_KEY_USER_ID];
    [params setValue:userName forKey:STRING_REQUEST_KEY_USER_NAME];
    [params setValue:[NSString stringWithFormat:@"%i", [UIDevice currentDevice].platformType] forKey:STRING_REQUEST_KEY_DEVICE_TYPE];
    [params setValue:[UIDevice currentDevice].platformString forKey:STRING_REQUEST_KEY_DEVICE_NAME];
    
#ifdef __DEBUG__
    NSLog(@"UPDATE USER INFO: %@", params);
#endif
    [_APIRequester queueWithType:ENUM_API_REQUEST_TYPE_USER_UPDATE_USER_INFO andRootURL:STRING_REQUEST_URL_USER_UPDATE_INFO andPostMethodKind:YES andParams:params andDelegate:self];
    
    [_APIRequester startQueue];
}

#pragma mark - FOREGROUND & BACKGROUND

- (void)applicationDidEnterBackground:(UIApplication *)application; {

}

- (void)applicationWillEnterForeground:(UIApplication *)application; {
    // USER ID
    NSString *userID = @"";
    
    // USER NAME
    NSString *userName = @"";
    
    // DEVICE UDID
    NSString *deviceUDID = [UIDevice currentDevice].deviceUDID;
    [UserDataManager Shared].userDeviceUDID = deviceUDID;
    
    
    // DEVICE TOKEN
    NSString *deviceToken = @"";
    if ([UserDataManager Shared].userRegisteredDeviceToken) {
        deviceToken = [UserDataManager Shared].userRegisteredDeviceToken;
        [UserDataManager Shared].userDeviceToken = [UserDataManager Shared].userRegisteredDeviceToken;
    }
    
    // ENTER FOREGROUND APP
    NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
    [params setValue:deviceToken forKey:STRING_REQUEST_KEY_DEVICE_TOKEN];
    [params setValue:deviceUDID forKey:STRING_REQUEST_KEY_DEVICE_UDID];
    [params setValue:userID forKey:STRING_REQUEST_KEY_USER_ID];
    [params setValue:userName forKey:STRING_REQUEST_KEY_USER_NAME];
    [params setValue:[NSString stringWithFormat:@"%i", [UIDevice currentDevice].platformType] forKey:STRING_REQUEST_KEY_DEVICE_TYPE];
    [params setValue:[UIDevice currentDevice].platformString forKey:STRING_REQUEST_KEY_DEVICE_NAME];
    
#ifdef __DEBUG__
    NSLog(@"ENTER FOREGROUND APP: %@", params);
#endif
    [_APIRequester queueWithType:ENUM_API_REQUEST_TYPE_ACTIONS_ENTER_FOREGROUND_APP andRootURL:STRING_REQUEST_URL_ACTIONS_ENTER_FOREGROUND_APP andPostMethodKind:YES andParams:params andDelegate:self];
    
    [_APIRequester startQueue];
}

#pragma mark - LOCAL NOTIFICATION

- (void)scheduleNotificationWithAlertDate:(NSDate*)date andAlertMessage:(NSString *)message
{
    UIApplication* app = [UIApplication sharedApplication];
    NSArray*    oldNotifications = [app scheduledLocalNotifications];
    
    // Clear out the old notification before scheduling a new one.
    if ([oldNotifications count] > 0)
        [app cancelAllLocalNotifications];
    
    // Create a new notification.
    UILocalNotification* alarm = [[UILocalNotification alloc] init];
    if (alarm)
    {
        alarm.fireDate = date;
        alarm.timeZone = [NSTimeZone defaultTimeZone];
        alarm.repeatInterval = 0;
        alarm.soundName = UILocalNotificationDefaultSoundName;
        alarm.alertBody = message;
        
        [app scheduleLocalNotification:alarm];
    }
}

- (void)showNotificationWithMessage:(NSString *)message andIsShowed:(BOOL)isShowed {
    UIView *lastView = ((UIViewController *)[_listOfViewController lastObject]).view;
    if (!_notificationView) {
        // VIEW
        _notificationView = [[UIView alloc] initWithFrame:CGRectMake(0, -40, lastView.frame.size.width, 40)];
        _notificationView.backgroundColor = [UIColor whiteColor];
        _notificationView.layer.masksToBounds = YES;
        _notificationView.layer.cornerRadius = 10;
        
        UIView *notificationView = [[UIView alloc] initWithFrame:CGRectMake(7, 10, 20, 20)];
        notificationView.layer.masksToBounds = YES;
        notificationView.layer.cornerRadius = 3;
        [_notificationView addSubview:notificationView];
        UIImageView *notificationImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, notificationView.frame.size.width, notificationView.frame.size.height)];
        UIImage *notificationImage = [UIImage imageNamed:@"Icon@2x.png"];
        [notificationImageView setImage:notificationImage];
        [notificationView addSubview:notificationImageView];
        
        UILabel *notificationMarginLbl = [[UILabel alloc] initWithFrame:CGRectMake(32, 2, 0.5, 36)];
        notificationMarginLbl.backgroundColor = [UIColor grayColor];
        [_notificationView addSubview:notificationMarginLbl];
        
        UILabel *notificationTitleLbl = [[UILabel alloc] initWithFrame:CGRectMake(40, 7, 528, 12)];
        notificationTitleLbl.backgroundColor = [UIColor clearColor];
        notificationTitleLbl.textColor = [UIColor blackColor];
        notificationTitleLbl.text = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];;
        notificationTitleLbl.font = [UIFont boldSystemFontOfSize:16];
        [_notificationView addSubview:notificationTitleLbl];
        
        _notificationMessageLbl = [[UILabel alloc] initWithFrame:CGRectMake(40, 22, 528, 12)];
        _notificationMessageLbl.backgroundColor = [UIColor clearColor];
        _notificationMessageLbl.textColor = [UIColor blackColor];
        _notificationMessageLbl.font = [UIFont systemFontOfSize:12];
        [_notificationView addSubview:_notificationMessageLbl];
    }
    
    // SET NEW TEXT
    if (_notificationMessageLbl) {
        _notificationMessageLbl.text = @"";
        if (message) {
            _notificationMessageLbl.text = message;
        }
    }
    
    [self.navigationController.view addSubview:_notificationView];
    
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:TIMER_CHANGING_VIEW];
    if (isShowed) {
        _notificationView.frame = CGRectMake(0, 0, lastView.frame.size.width, 40);
        
        // PLAY SOUND
        // SOUND
        SystemSoundID soundID;
        
        // create the sound
        NSString *sndpath = [[NSBundle mainBundle] pathForResource:STRING_SOUND_NOTIFICATION ofType:nil];
        CFURLRef baseURL = (__bridge CFURLRef)[NSURL fileURLWithPath:sndpath];
        
        // Identify it as not a UI Sound
        AudioServicesCreateSystemSoundID(baseURL, &soundID);
        AudioServicesPropertyID flag = 0;  // 0 means always play
        AudioServicesSetProperty(kAudioServicesPropertyIsUISound, sizeof(SystemSoundID), &soundID, sizeof(AudioServicesPropertyID), &flag);
        
        if ([MPMusicPlayerController iPodMusicPlayer].playbackState ==  MPMusicPlaybackStatePlaying)
            AudioServicesPlayAlertSound(soundID);
        else
            AudioServicesPlaySystemSound(soundID);
    }
    else {
        _notificationView.frame = CGRectMake(0, -40, lastView.frame.size.width, 40);
    }
    [UIView commitAnimations];
    
    if (isShowed) {
        [self performSelector:@selector(hideNotification) withObject:nil afterDelay:4];
    }
}

- (void)hideNotification {
    if (_notificationView) {
        [self showNotificationWithMessage:nil andIsShowed:NO];
    }
}

#pragma mark - REMOTE NOTIFICATION
- (void)didReceiveRemoteNotification:(NSDictionary *)userInfo andNotificationType:(enumRemoveNotificationType)type {
    
}

#pragma mark - APIRequesterProtocol

- (void)requestFinished:(ASIHTTPRequest *)request andType:(ENUM_API_REQUEST_TYPE)type {
#ifdef __DEBUG__
    NSLog(@"requestFinished %@, request.responseStatusCode: %i", request.responseString, request.responseStatusCode);
#endif
    
    [[AppViewController Shared] isRequesting:NO andRequestType:ENUM_API_REQUEST_TYPE_INVALID andFrame:CGRectZero];
    
    NSError *error;
    SBJSON *sbJSON = [SBJSON new];
    
    if (![sbJSON objectWithString:[request responseString] error:&error] || request.responseStatusCode != 200 || !request) {
//        if (![ASIHTTPRequest isNetworkReachable]) {
//            ALERT(STRING_ALERT_CONNECTION_ERROR_TITLE, STRING_ALERT_SERVER_ERROR);
//        }
#ifdef __DEBUG__
        NSMutableDictionary *jsonData = [sbJSON objectWithString:[request responseString] error:&error];
        if ((NSNull *)[jsonData objectForKey:STRING_RESPONSE_KEY_MESSAGE] != [NSNull null]) {
            ALERT([NSString stringWithFormat:@"%i", request.responseStatusCode], [jsonData objectForKey:STRING_RESPONSE_KEY_MESSAGE]);
        }
#else
        if (type != ENUM_API_REQUEST_TYPE_USER_UPDATE_DEVICE_TOKEN && type != ENUM_API_REQUEST_TYPE_USER_UPDATE_DEVICE_UDID && type != ENUM_API_REQUEST_TYPE_USER_UPDATE_USER_INFO) {
            ALERT(STRING_ALERT_CONNECTION_ERROR_TITLE, STRING_ALERT_SERVER_ERROR);
        }
#endif
        return;
    }
    
    NSMutableDictionary *jsonData = [[sbJSON objectWithString:[request responseString] error:&error] objectForKey:STRING_RESPONSE_KEY_MESSAGE];
    
    if (type == ENUM_API_REQUEST_TYPE_USER_UPDATE_USER_INFO) {
        NSLog(@"Update User Info is Success.");
        if ((NSNull *)[jsonData objectForKey:STRING_RESPONSE_KEY_USER_ID] != [NSNull null]) {
            [UserDataManager Shared].userID = [jsonData objectForKey:STRING_RESPONSE_KEY_USER_ID];
        }
        if ((NSNull *)[jsonData objectForKey:STRING_RESPONSE_KEY_USER_NAME] != [NSNull null]) {
            [UserDataManager Shared].userFullName = [jsonData objectForKey:STRING_RESPONSE_KEY_USER_NAME];
        }
        if ((NSNull *)[jsonData objectForKey:STRING_RESPONSE_KEY_DEVICE_UDID] != [NSNull null]) {
            [UserDataManager Shared].userDeviceUDID = [jsonData objectForKey:STRING_RESPONSE_KEY_DEVICE_UDID];
        }
        if ((NSNull *)[jsonData objectForKey:STRING_RESPONSE_KEY_DEVICE_TOKEN] != [NSNull null]) {
            [UserDataManager Shared].userDeviceToken = [jsonData objectForKey:STRING_RESPONSE_KEY_DEVICE_TOKEN];
        }
        if ((NSNull *)[jsonData objectForKey:STRING_RESPONSE_KEY_NOTIFY_ME] != [NSNull null]) {
            [UserDataManager Shared].userNotifyMe = [jsonData objectForKey:STRING_RESPONSE_KEY_NOTIFY_ME];
        }
    
        [[UserDataManager Shared] save];
    }
    
}

- (void)requestFailed:(ASIHTTPRequest *)request andType:(ENUM_API_REQUEST_TYPE)type {
#ifdef __DEBUG__
    NSLog(@"requestFailed %@, request.responseStatusCode: %i", request.responseString, request.responseStatusCode);
#endif
    
    [[AppViewController Shared] isRequesting:NO andRequestType:ENUM_API_REQUEST_TYPE_INVALID andFrame:CGRectZero];
    
    if (![ASIHTTPRequest isNetworkReachable] && type != ENUM_API_REQUEST_TYPE_USER_UPDATE_DEVICE_TOKEN && type != ENUM_API_REQUEST_TYPE_USER_UPDATE_DEVICE_UDID && type != ENUM_API_REQUEST_TYPE_USER_UPDATE_USER_INFO) {
        ALERT(STRING_ALERT_CONNECTION_ERROR_TITLE, STRING_ALERT_CONNECTION_ERROR);
    }
}

@end
